--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
tests/backend/test_conversation_load_fast.py c0b0ddffd735a0d007c1be9a5e8563ec42fdafc0 (c0b0ddff) Text, 5.00 KB
T8b949e# SPDX-License-Identifier: 0BSD
T8b949e"""Regression tests for fast conversation list and heavy thread loads."""
Tff7b72import T7ee787json
Tff7b72import T7ee787secrets
Tff7b72import T7ee787tempfile
Tff7b72import T7ee787time
Tff7b72import T7ee787unittest
Tff7b72from T7ee787meshchatxT7ee787.T7ee787srcT7ee787.T7ee787backendT7ee787.T7ee787database Tff7b72import Te6edf3Database
Tff7b72from T7ee787meshchatxT7ee787.T7ee787srcT7ee787.T7ee787backendT7ee787.T7ee787lxmf_utils Tff7b72import Te6edf3convert_db_lxmf_message_to_dict
Tff7b72from T7ee787meshchatxT7ee787.T7ee787srcT7ee787.T7ee787backendT7ee787.T7ee787message_handler Tff7b72import Te6edf3MessageHandler
Tff7b72def Td2a8ff_messageTb4b4b4(Te6edf3peer_hashTb4b4b4, Te6edf3iTb4b4b4, Tff7b72*Tb4b4b4, Te6edf3fieldsTff7b72=Ta5d6ff"Tffd700{}Ta5d6ff"Tb4b4b4, Te6edf3contentTff7b72=Ta5d6ff"Ta5d6ffhelloTa5d6ff"Tb4b4b4)Tb4b4b4:
Tff7b72return Tb4b4b4{
Ta5d6ff"Ta5d6ffhashTa5d6ff"Tb4b4b4: Te6edf3secretsTff7b72.Td2a8fftoken_hexTb4b4b4(T79c0ff16Tb4b4b4)Tb4b4b4,
Ta5d6ff"Ta5d6ffsource_hashTa5d6ff"Tb4b4b4: Te6edf3peer_hashTb4b4b4,
Ta5d6ff"Ta5d6ffdestination_hashTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6fflocalhashlocalhashlocalhashlo12Ta5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffpeer_hashTa5d6ff"Tb4b4b4: Te6edf3peer_hashTb4b4b4,
Ta5d6ff"Ta5d6ffstateTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffdeliveredTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffprogressTa5d6ff"Tb4b4b4: T79c0ff1.0Tb4b4b4,
Ta5d6ff"Ta5d6ffis_incomingTa5d6ff"Tb4b4b4: T79c0ff1Tb4b4b4,
Ta5d6ff"Ta5d6ffmethodTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffdirectTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffdelivery_attemptsTa5d6ff"Tb4b4b4: T79c0ff1Tb4b4b4,
Ta5d6ff"Ta5d6ffnext_delivery_attempt_atTa5d6ff"Tb4b4b4: Tff7b72NoneTb4b4b4,
Ta5d6ff"Ta5d6fftitleTa5d6ff"Tb4b4b4: Ta5d6fffTa5d6ff"Ta5d6fftTffd700{Te6edf3iTffd700}Ta5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffcontentTa5d6ff"Tb4b4b4: Te6edf3contentTb4b4b4,
Ta5d6ff"Ta5d6fffieldsTa5d6ff"Tb4b4b4: Te6edf3fieldsTb4b4b4,
Ta5d6ff"Ta5d6fftimestampTa5d6ff"Tb4b4b4: Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4) Tff7b72- Te6edf3iTb4b4b4,
Ta5d6ff"Ta5d6ffrssiTa5d6ff"Tb4b4b4: Tff7b72-T79c0ff50Tb4b4b4,
Ta5d6ff"Ta5d6ffsnrTa5d6ff"Tb4b4b4: T79c0ff5.0Tb4b4b4,
Ta5d6ff"Ta5d6ffqualityTa5d6ff"Tb4b4b4: T79c0ff3Tb4b4b4,
Ta5d6ff"Ta5d6ffis_spamTa5d6ff"Tb4b4b4: T79c0ff0Tb4b4b4,
Ta5d6ff"Ta5d6ffreply_to_hashTa5d6ff"Tb4b4b4: Tff7b72NoneTb4b4b4,
Tb4b4b4}
Tff7b72class T56d364TestConversationLoadFastTb4b4b4(Te6edf3unittestTff7b72.Td2a8ffTestCaseTb4b4b4)Tb4b4b4:
Tff7b72def Td2a8ffsetUpTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72from T7ee787meshchatxT7ee787.T7ee787srcT7ee787.T7ee787backendT7ee787.T7ee787databaseT7ee787.T7ee787provider Tff7b72import Te6edf3DatabaseProvider
Tff7b72if Te6edf3DatabaseProviderTff7b72.Td2a8ff_instance Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Te6edf3DatabaseProviderTff7b72.Td2a8ff_instanceTff7b72.Td2a8ffclose_allTb4b4b4(Tb4b4b4)
Te6edf3DatabaseProviderTff7b72.Td2a8ff_instance Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8fftmp Tff7b72= Te6edf3tempfileTff7b72.Td2a8ffTemporaryDirectoryTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffdb Tff7b72= Te6edf3DatabaseTb4b4b4(Ta5d6fffTa5d6ff"Tffd700{Tff7b72selfTff7b72.Td2a8fftmpTff7b72.Td2a8ffnameTffd700}Ta5d6ff/database.dbTa5d6ff"Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffdbTff7b72.Td2a8ffinitializeTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffhandler Tff7b72= Te6edf3MessageHandlerTb4b4b4(Tff7b72selfTff7b72.Td2a8ffdbTb4b4b4)
Tff7b72def Td2a8fftearDownTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72from T7ee787meshchatxT7ee787.T7ee787srcT7ee787.T7ee787backendT7ee787.T7ee787databaseT7ee787.T7ee787provider Tff7b72import Te6edf3DatabaseProvider
Tff7b72selfTff7b72.Td2a8ffdbTff7b72.Td2a8ffcloseTb4b4b4(Tb4b4b4)
Tff7b72if Te6edf3DatabaseProviderTff7b72.Td2a8ff_instance Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Te6edf3DatabaseProviderTff7b72.Td2a8ff_instanceTff7b72.Td2a8ffclose_allTb4b4b4(Tb4b4b4)
Te6edf3DatabaseProviderTff7b72.Td2a8ff_instance Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8fftmpTff7b72.Td2a8ffcleanupTb4b4b4(Tb4b4b4)
Tff7b72def Td2a8fftest_upsert_stores_fields_meta_without_bytesTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Te6edf3peer Tff7b72= Te6edf3secretsTff7b72.Td2a8fftoken_hexTb4b4b4(T79c0ff16Tb4b4b4)
Te6edf3big_b64 Tff7b72= Ta5d6ff"Ta5d6ffATa5d6ff" Tff7b72* T79c0ff80000
Te6edf3fields Tff7b72= Tb4b4b4{
Ta5d6ff"Ta5d6ffimageTa5d6ff"Tb4b4b4: Tb4b4b4{
Ta5d6ff"Ta5d6ffimage_typeTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffpngTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffimage_bytesTa5d6ff"Tb4b4b4: Te6edf3big_b64Tb4b4b4,
Tb4b4b4}Tb4b4b4,
Tb4b4b4}
Tff7b72selfTff7b72.Td2a8ffdbTff7b72.Td2a8ffmessagesTff7b72.Td2a8ffupsert_lxmf_messageTb4b4b4(Te6edf3_messageTb4b4b4(Te6edf3peerTb4b4b4, T79c0ff0Tb4b4b4, Te6edf3fieldsTff7b72=Te6edf3fieldsTb4b4b4)Tb4b4b4)
Te6edf3row Tff7b72= Tff7b72selfTff7b72.Td2a8ffdbTff7b72.Td2a8ffproviderTff7b72.Td2a8fffetchoneTb4b4b4(
Ta5d6ff"Ta5d6ffSELECT fields, fields_meta, has_image, has_audio, has_files Ta5d6ff"
Ta5d6ff"Ta5d6ffFROM lxmf_messages WHERE peer_hash = ?Ta5d6ff"Tb4b4b4,
Tb4b4b4(Te6edf3peerTb4b4b4,Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertEqualTb4b4b4(Te6edf3rowTb4b4b4[Ta5d6ff"Ta5d6ffhas_imageTa5d6ff"Tb4b4b4]Tb4b4b4, T79c0ff1Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertEqualTb4b4b4(Te6edf3rowTb4b4b4[Ta5d6ff"Ta5d6ffhas_audioTa5d6ff"Tb4b4b4]Tb4b4b4, T79c0ff0Tb4b4b4)
Te6edf3meta Tff7b72= Te6edf3jsonTff7b72.Td2a8ffloadsTb4b4b4(Te6edf3rowTb4b4b4[Ta5d6ff"Ta5d6fffields_metaTa5d6ff"Tb4b4b4]Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertIsNoneTb4b4b4(Te6edf3metaTb4b4b4[Ta5d6ff"Ta5d6ffimageTa5d6ff"Tb4b4b4]Tb4b4b4[Ta5d6ff"Ta5d6ffimage_bytesTa5d6ff"Tb4b4b4]Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertEqualTb4b4b4(Te6edf3metaTb4b4b4[Ta5d6ff"Ta5d6ffimageTa5d6ff"Tb4b4b4]Tb4b4b4[Ta5d6ff"Ta5d6ffimage_typeTa5d6ff"Tb4b4b4]Tb4b4b4, Ta5d6ff"Ta5d6ffpngTa5d6ff"Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertGreaterTb4b4b4(Te6edf3metaTb4b4b4[Ta5d6ff"Ta5d6ffimageTa5d6ff"Tb4b4b4]Tb4b4b4[Ta5d6ff"Ta5d6ffimage_sizeTa5d6ff"Tb4b4b4]Tb4b4b4, T79c0ff0Tb4b4b4)
T8b949e# Full blob remains available for the attachment endpoint.
Tff7b72selfTff7b72.Td2a8ffassertInTb4b4b4(Te6edf3big_b64Tb4b4b4, Te6edf3rowTb4b4b4[Ta5d6ff"Ta5d6fffieldsTa5d6ff"Tb4b4b4]Tb4b4b4)
Tff7b72def Td2a8fftest_conversation_messages_do_not_return_huge_fields_blobTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Te6edf3peer Tff7b72= Te6edf3secretsTff7b72.Td2a8fftoken_hexTb4b4b4(T79c0ff16Tb4b4b4)
Te6edf3big_b64 Tff7b72= Ta5d6ff"Ta5d6ffBTa5d6ff" Tff7b72* T79c0ff120000
Te6edf3fields Tff7b72= Tb4b4b4{
Ta5d6ff"Ta5d6ffimageTa5d6ff"Tb4b4b4: Tb4b4b4{
Ta5d6ff"Ta5d6ffimage_typeTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffjpegTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffimage_bytesTa5d6ff"Tb4b4b4: Te6edf3big_b64Tb4b4b4,
Tb4b4b4}Tb4b4b4,
Tb4b4b4}
Tff7b72for Te6edf3i Tff7b72in Tffa657rangeTb4b4b4(T79c0ff40Tb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffdbTff7b72.Td2a8ffmessagesTff7b72.Td2a8ffupsert_lxmf_messageTb4b4b4(
Te6edf3_messageTb4b4b4(Te6edf3peerTb4b4b4, Te6edf3iTb4b4b4, Te6edf3fieldsTff7b72=Te6edf3fields Tff7b72if Te6edf3i Tff7b72% T79c0ff2 Tff7b72== T79c0ff0 Tff7b72else Ta5d6ff"Tffd700{}Ta5d6ff"Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Te6edf3rows Tff7b72= Tff7b72selfTff7b72.Td2a8ffhandlerTff7b72.Td2a8ffget_conversation_messagesTb4b4b4(Ta5d6ff"Ta5d6fflocalTa5d6ff"Tb4b4b4, Te6edf3peerTb4b4b4, Te6edf3limitTff7b72=T79c0ff30Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertEqualTb4b4b4(Tffa657lenTb4b4b4(Te6edf3rowsTb4b4b4)Tb4b4b4, T79c0ff30Tb4b4b4)
Tff7b72for Te6edf3row Tff7b72in Te6edf3rowsTb4b4b4:
Te6edf3row Tff7b72= Tffa657dictTb4b4b4(Te6edf3rowTb4b4b4)
Te6edf3fields_value Tff7b72= Te6edf3rowTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6fffieldsTa5d6ff"Tb4b4b4)
Tff7b72if Te6edf3fields_valueTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffassertLessTb4b4b4(
Tffa657lenTb4b4b4(Te6edf3fields_valueTb4b4b4)Tb4b4b4,
T79c0ff20000Tb4b4b4,
Ta5d6ff"Ta5d6ffconversation message query returned oversized fieldsTa5d6ff"Tb4b4b4,
Tb4b4b4)
Te6edf3converted Tff7b72= Te6edf3convert_db_lxmf_message_to_dictTb4b4b4(Te6edf3rowTb4b4b4)
Tff7b72if Te6edf3rowTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffhas_imageTa5d6ff"Tb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffassertInTb4b4b4(Ta5d6ff"Ta5d6ffimageTa5d6ff"Tb4b4b4, Te6edf3convertedTb4b4b4[Ta5d6ff"Ta5d6fffieldsTa5d6ff"Tb4b4b4]Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertIsNoneTb4b4b4(Te6edf3convertedTb4b4b4[Ta5d6ff"Ta5d6fffieldsTa5d6ff"Tb4b4b4]Tb4b4b4[Ta5d6ff"Ta5d6ffimageTa5d6ff"Tb4b4b4]Tb4b4b4[Ta5d6ff"Ta5d6ffimage_bytesTa5d6ff"Tb4b4b4]Tb4b4b4)
Tff7b72def Td2a8fftest_conversations_list_uses_flags_not_fields_columnTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Te6edf3peer Tff7b72= Te6edf3secretsTff7b72.Td2a8fftoken_hexTb4b4b4(T79c0ff16Tb4b4b4)
Te6edf3big_b64 Tff7b72= Ta5d6ff"Ta5d6ffCTa5d6ff" Tff7b72* T79c0ff90000
Tff7b72selfTff7b72.Td2a8ffdbTff7b72.Td2a8ffmessagesTff7b72.Td2a8ffupsert_lxmf_messageTb4b4b4(
Te6edf3_messageTb4b4b4(
Te6edf3peerTb4b4b4,
T79c0ff0Tb4b4b4,
Te6edf3fieldsTff7b72=Tb4b4b4{
Ta5d6ff"Ta5d6ffimageTa5d6ff"Tb4b4b4: Tb4b4b4{Ta5d6ff"Ta5d6ffimage_typeTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffpngTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffimage_bytesTa5d6ff"Tb4b4b4: Te6edf3big_b64Tb4b4b4}Tb4b4b4,
Tb4b4b4}Tb4b4b4,
Te6edf3contentTff7b72=Ta5d6ff"Ta5d6ff"Tb4b4b4,
Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Te6edf3rows Tff7b72= Tff7b72selfTff7b72.Td2a8ffhandlerTff7b72.Td2a8ffget_conversationsTb4b4b4(Ta5d6ff"Ta5d6fflocalTa5d6ff"Tb4b4b4, Te6edf3limitTff7b72=T79c0ff10Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertGreaterEqualTb4b4b4(Tffa657lenTb4b4b4(Te6edf3rowsTb4b4b4)Tb4b4b4, T79c0ff1Tb4b4b4)
Te6edf3row Tff7b72= Tffa657dictTb4b4b4(Te6edf3rowsTb4b4b4[T79c0ff0Tb4b4b4]Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertEqualTb4b4b4(Te6edf3rowTb4b4b4[Ta5d6ff"Ta5d6ffpeer_hashTa5d6ff"Tb4b4b4]Tb4b4b4, Te6edf3peerTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertEqualTb4b4b4(Te6edf3rowTb4b4b4[Ta5d6ff"Ta5d6ffhas_imageTa5d6ff"Tb4b4b4]Tb4b4b4, T79c0ff1Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertEqualTb4b4b4(Te6edf3rowTb4b4b4[Ta5d6ff"Ta5d6ffhas_attachmentsTa5d6ff"Tb4b4b4]Tb4b4b4, T79c0ff1Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertNotInTb4b4b4(Ta5d6ff"Ta5d6fffieldsTa5d6ff"Tb4b4b4, Te6edf3rowTff7b72.Td2a8ffkeysTb4b4b4(Tb4b4b4)Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertInTb4b4b4(Ta5d6ff"Ta5d6ffhas_contact_imageTa5d6ff"Tb4b4b4, Te6edf3rowTff7b72.Td2a8ffkeysTb4b4b4(Tb4b4b4)Tb4b4b4)
Te6edf3summary Tff7b72= Tff7b72selfTff7b72.Td2a8ffdbTff7b72.Td2a8ffproviderTff7b72.Td2a8fffetchoneTb4b4b4(
Ta5d6ff"Ta5d6ffSELECT has_image FROM lxmf_conversation_summaries WHERE peer_hash = ?Ta5d6ff"Tb4b4b4,
Tb4b4b4(Te6edf3peerTb4b4b4,Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertEqualTb4b4b4(Te6edf3summaryTb4b4b4[Ta5d6ff"Ta5d6ffhas_imageTa5d6ff"Tb4b4b4]Tb4b4b4, T79c0ff1Tb4b4b4)
Tff7b72if Tff7b72__name__ Tff7b72== Ta5d6ff"Ta5d6ff__main__Ta5d6ff"Tb4b4b4:
Te6edf3unittestTff7b72.Td2a8ffmainTb4b4b4(Tb4b4b4)
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────